﻿using StockTradTest;
using StockTradTest.Data;
using StockTradTest.strategy;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestGraphic
{
    public partial class Form3 : Form
    {
        string record = "";
        Graphics graphics;
        //绘图用缓存
        Bitmap bmp;
        readonly Pen pen;
        readonly Brush brush;

        #region 控件大小随窗体大小等比例缩放
        readonly private float x;//定义当前窗体的宽度
        readonly private float y;//定义当前窗体的高度
        private void SetTag(Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    SetTag(con);
                }
            }


        }
        private void SetControls(float newx, float newy, Control cons)
        {
            //遍历窗体中的控件，重新设置控件的值
            foreach (Control con in cons.Controls)
            {
                //获取控件的Tag属性值，并分割后存储字符串数组
                if (con.Tag != null)
                {
                    string[] mytag = con.Tag.ToString().Split(new char[] { ';' });
                    //根据窗体缩放的比例确定控件的值
                    con.Width = Convert.ToInt32(System.Convert.ToSingle(mytag[0]) * newx);//宽度
                    con.Height = Convert.ToInt32(System.Convert.ToSingle(mytag[1]) * newy);//高度
                    con.Left = Convert.ToInt32(System.Convert.ToSingle(mytag[2]) * newx);//左边距
                    con.Top = Convert.ToInt32(System.Convert.ToSingle(mytag[3]) * newy);//顶边距
                    Single currentSize = System.Convert.ToSingle(mytag[4]) * newy;//字体大小
                    con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                    if (con.Controls.Count > 0)
                    {
                        SetControls(newx, newy, con);
                    }
                }
            }
        }
        #endregion
        private async Task RunOnceAsync(string code)
        {
            await foreach (string str in GetStockHistory.UpdateDayAsync(code))
            {
                label_Log.Text = str;
            }
            label_Log.Text = "";
        }
        public Form3()
        {
            pen = new Pen(Color.Black, 1);
            brush = new SolidBrush(Color.Black);
            InitializeComponent();
            x = this.Width;
            y = this.Height;
            SetTag(this);

            bmp = new Bitmap(Width, Height);
            graphics = Graphics.FromImage(bmp);


            //Clear();
            textBox_Code.Text = "601166";
            progressBar.Visible = false;
        }
        private void Clear()
        {
            graphics.Clear(Color.WhiteSmoke);
            graphics.FillRectangle(brush, new RectangleF(2, 2, Width - 20, (int)(Height - 100 - 1)));
            graphics.DrawRectangle(pen, new Rectangle(1, 1, Width - (int)pen.Width - 18, (int)(Height - 100)));
            record = "";
        }

        private void Disable(bool tof)
        {
            if(tof)
            {
                button_Calc.Enabled = false;
                button_Log.Enabled = false;
            }
            else
            {
                button_Calc.Enabled = true;
                button_Log.Enabled = true;
            }
        }
        private async void Button_Calc_ClickAsync(object sender, EventArgs e)
        {
            Disable(true);
            Clear();
            //MessageBox.Show(textBox_Code.Text);
            await RunOnceAsync(textBox_Code.Text);
            label_Log.Text = "更新完成,开始计算策略";
            progressBar.Visible = true;
            progressBar.Value = 0;
            TestTradBase.isRecord = true;
            //测试位置
            Test1();
            //测试结束
            label_Log.Text = "策略执行完成";
            progressBar.Value = 100;
            progressBar.Visible = false;
            Disable(false);
        }

        void Test1()
        {
            string[] temp = textBox_Variable.ToString().Split(',');
            if(!int.TryParse(temp[0], out int startDate) || !int.TryParse(temp[1], out int endDate))
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            else if(endDate < startDate)
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            List<double> basefunds = MyStrategy.TradBase(textBox_Code.Text,startDate,endDate);
            if(basefunds == null || basefunds.Count == 0)
            {

                return;
            }
            record += string.Format("基础数据:\n{0}\n", TestTradBase.record);
            progressBar.Value = 10;
            List<double> funds0 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 5,out List<int> buyOrsell,true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 5, TestTradBase.record);
            progressBar.Value = 20;
            List<double> funds1 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 10, out buyOrsell, true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 10, TestTradBase.record);
            progressBar.Value = 30;
            List<double> funds2 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 20, out buyOrsell, true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 20, TestTradBase.record);
            progressBar.Value = 40;
            List<double> funds3 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 30, out buyOrsell, true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 30, TestTradBase.record);
            progressBar.Value = 50;
            List<double> funds4 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 60, out buyOrsell, true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 60, TestTradBase.record);
            progressBar.Value = 60;
            List<double> funds5 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 120, out buyOrsell, true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 120, TestTradBase.record);
            progressBar.Value = 70;
            List<double> funds6 = MyStrategy.TradeMiddleTest(textBox_Code.Text, 250, out buyOrsell, true, startDate, endDate);
            record += string.Format("策略变量{0}:\n{1}\n", 250, TestTradBase.record);
            progressBar.Value = 80;

            double[] data = new double[] { funds0.Min(), funds0.Max(),
                funds1.Min(), funds1.Max(),
                funds2.Min(), funds2.Max(),
                funds3.Min(), funds3.Max(),
                funds4.Min(), funds4.Max(),
                funds5.Min(), funds5.Max(),
                funds6.Min(), funds6.Max(), basefunds.Min(),basefunds.Max() };
            double minData = data.Min();
            double maxData = data.Max();
            progressBar.Value = 90;
            DrawFund(basefunds, minData, maxData, Color.White);
            DrawFund(funds0, minData, maxData, Color.Red);
            DrawFund(funds1, minData, maxData, Color.Orange);
            DrawFund(funds2, minData, maxData, Color.Yellow);
            DrawFund(funds3, minData, maxData, Color.Green);
            DrawFund(funds4, minData, maxData, Color.Blue);
            DrawFund(funds5, minData, maxData, Color.Indigo);
            DrawFund(funds6, minData, maxData, Color.Purple);
        }
        void Test2()
        {
            string[] temp = textBox_Variable.ToString().Split(',');
            if (!int.TryParse(temp[0], out int startDate) || !int.TryParse(temp[1], out int endDate))
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            else if (endDate < startDate)
            {
                startDate = 0;
                endDate = int.MaxValue;
            }
            List<double> basefunds = MyStrategy.TradBase(textBox_Code.Text, startDate, endDate);
            if (basefunds == null || basefunds.Count == 0)
            {

                return;
            }
            record += string.Format("基础数据:\n{0}\n", TestTradBase.record);
            progressBar.Value = 10;
            List<double> funds0 = MyStrategy.TradeMaTest(textBox_Code.Text, 5);
            record += string.Format("策略变量{0}:\n{1}\n", 5, TestTradBase.record);
            progressBar.Value = 20;
            List<double> funds1 = MyStrategy.TradeMaTest(textBox_Code.Text, 10);
            record += string.Format("策略变量{0}:\n{1}\n", 10, TestTradBase.record);
            progressBar.Value = 30;
            List<double> funds2 = MyStrategy.TradeMaTest(textBox_Code.Text, 20);
            record += string.Format("策略变量{0}:\n{1}\n", 20, TestTradBase.record);
            progressBar.Value = 40;
            List<double> funds3 = MyStrategy.TradeMaTest(textBox_Code.Text, 30);
            record += string.Format("策略变量{0}:\n{1}\n", 30, TestTradBase.record);
            progressBar.Value = 50;
            List<double> funds4 = MyStrategy.TradeMaTest(textBox_Code.Text, 60);
            record += string.Format("策略变量{0}:\n{1}\n", 60, TestTradBase.record);
            progressBar.Value = 60;
            List<double> funds5 = MyStrategy.TradeMaTest(textBox_Code.Text, 120);
            record += string.Format("策略变量{0}:\n{1}\n", 120, TestTradBase.record);
            progressBar.Value = 70;
            List<double> funds6 = MyStrategy.TradeMaTest(textBox_Code.Text, 250);
            record += string.Format("策略变量{0}:\n{1}\n", 250, TestTradBase.record);
            progressBar.Value = 80;

            double[] data = new double[] { funds0.Min(), funds0.Max(),
                funds1.Min(), funds1.Max(),
                funds2.Min(), funds2.Max(),
                funds3.Min(), funds3.Max(),
                funds4.Min(), funds4.Max(),
                funds5.Min(), funds5.Max(),
                funds6.Min(), funds6.Max(), basefunds.Min(),basefunds.Max() };
            double minData = data.Min();
            double maxData = data.Max();
            progressBar.Value = 90;
            DrawFund(basefunds, minData, maxData, Color.White);
            DrawFund(funds0, minData, maxData, Color.Red);
            DrawFund(funds1, minData, maxData, Color.Orange);
            DrawFund(funds2, minData, maxData, Color.Yellow);
            DrawFund(funds3, minData, maxData, Color.Green);
            DrawFund(funds4, minData, maxData, Color.Blue);
            DrawFund(funds5, minData, maxData, Color.Indigo);
            DrawFund(funds6, minData, maxData, Color.Purple);
        }

        /// <summary>
        /// 在图上绘制资金线
        /// </summary>
        /// <param name="code">股票代码</param>
        /// <param name="n">ma天数</param>
        /// <param name="startCount">开始数据</param>
        private void DrawFund(List<double> data, double minData, double maxData, Color color)
        {
            double heightLength = Height - 100 - 10;
            double widthLength = Width - 20;
            double step = widthLength / data.Count;


            List<Point> points = new List<Point>();
            double length = maxData - minData;
            for (int i = 0; i < data.Count; i++)
            {
                points.Add(new Point((int)(i * step + 4), 5 + (int)(heightLength - (data[i] - minData) / length * heightLength)));
            }
            if (points.Count > 0) graphics.DrawLines(new Pen(color, 1), points.ToArray());


        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            this.CreateGraphics().DrawImage(bmp, 0, 0);
        }



        private void Form1_Resize(object sender, EventArgs e)
        {
            float newx = (this.Width) / x;
            float newy = (this.Height) / y;
            SetControls(newx, newy, this);
            bmp = new Bitmap(Width, Height);
            graphics = Graphics.FromImage(bmp);
            Clear();
        }

        private void Button_Log_Click(object sender, EventArgs e)
        {
            TextRecord.Record(record, true);
            TextRecord.OpenRecord();
        }

        private void Form3_FormClosed(object sender, FormClosedEventArgs e)
        {
            Form1.inFocus = true;
        }
    }
}
